#ifndef _COMM_HPP_//条件编译，如果没有定义 _COMM_HPP就执行下面的代码
#define _COMM_HPP_

#include<iostream>
#include<cstring>
#include<cstdlib>
#include <sys/ipc.h>
#include <sys/shm.h>
#include<cstdio>

#define PATHNAME "." //已存在的文件路径，'.'表示的就是当前路径-----ps(最好还是绝对路径)
#define PRJD_ID 0x77 //随便一个数都可以
#define MAX_SIZE 4096 //创建的共享内存的大小


key_t getkey()//获得getkey
{
    key_t k = ftok( PATHNAME , PRJD_ID );
    if(k < 0)//失败返回-1
    {
        //cin,cout,cerr---->stdin,stdout,stderr--->0,1,2
        std::cerr << errno << ":" <<strerror(errno) <<std::endl;//输出标准错误
        exit(1);//没有创建key值成功就直接退出
    }
    return k;
}

int getShmHelper(key_t k ,int flags)
{
    int shmid = shmget(k , MAX_SIZE, flags );
    if(shmid < 0)
    {
        std::cerr << errno << ":" << strerror(errno) << std::endl;
        exit(2);//没有创建成功就直接退出
    }
    return shmid;
}

int getShm(key_t k)//获取共享内存
{
    return getShmHelper(k,IPC_CREAT);
}

int createShm(key_t k )//创建共享内存
{
    return getShmHelper(k , IPC_CREAT | IPC_EXCL | 0600);
}


void * attachShm(int shmid)//挂接---将进程与共享内存关联起来----返回的是共享内存的起始
{ 
    void * mem = shmat(shmid , nullptr , 0);
    if((long long)mem == -1)
    {
        std::cerr << errno <<":"<<strerror(errno)<<std::endl;
        exit(3);//如果关联失败就没必要进行下去了
    }
    return mem;
}

void detachShm(void* start)//去关联
{
    if(shmdt(start) == -1)
    {
        std::cerr << errno << ":"<<strerror(errno)<<std::endl;
    }
}

void delShm(int shmid)//删除共享内存
{
    if(shmctl(shmid,IPC_RMID,NULL) == -1)
    {
        std::cerr << errno<<":" <<strerror(errno)<<std::endl;
    }
}


#endif//条件编译结束